package com.kitty.game.equip.handler;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.ServerService;
import com.kitty.game.equip.message.RespOperateResult;
import com.kitty.game.role.model.Role;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.config.Equip;
import com.kitty.game.enter.RespGeneralNotify;
import com.kitty.game.equip.EquipDataPool;
import com.kitty.game.equip.UpgradeType;
import com.kitty.listener.EventDispatcher;
import com.kitty.listener.EventType;
import com.kitty.listener.event.EquipUpgradeLevelChangeEvent;
import com.kitty.common.model.Reason;
import com.kitty.mina.message.MessagePusher;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import static com.kitty.game.utils.Const.MONEY_NAME;
import static com.kitty.game.utils.Const.ROLE_RESOURCE_NOT_ENOUGH;
import static com.kitty.game.utils.Const.WEAPON;
import static com.kitty.game.utils.NotifyModules.NOTIFY_EQUIP_UPGRADE_OK;

@Component("EquipUpgrade")
@Slf4j
public class EquipUpgradeHandler extends UpgradeHandler {

    /**
     * 武器需要的改造度
     */
    private static final List<Integer> WEAPON_PROGRESS = Arrays.asList(10, 15, 20, 2000, 20000, 80000, 400000, 2000000, 10000000, 50000000, 250000000, 1250000000);
    /**
     * 防具需要的改造度
     */
    private static final List<Integer> ARMOR_PROGRESS = Arrays.asList(3, 5, 7, 700, 7000, 30000, 150000, 700000, 3500000, 17500000, 85700000, 437500000);
    private static final String LINGSHI = "超级灵石";
    private static final String JINGSHI = "超级晶石";
    private static final String SUCCESS = "恭喜，改造成功了！装备的改造等级从#R{0}#n级提升到#R{1}#n级。";
    private static final String FAIL = "真遗憾，改造失败了！改造完成度增加{0}%，目前改造完成度已达{1}%。";
    private static final String FAIL_MESSAGE = "#R{0}#n是未鉴定装备，无法进行改造。";
    private static final String FAIL_MESSAGE1 = "#R手动#n改造已到最高6级，请去#R管神工#n处进行一键改造。";
    /**
     * 使用银元宝一键改造
     */
    private static final String SIVER = "1";
    /**
     * 使用金元宝一键改造
     */
    private static final String GOLD = "0";


    @Override
    public String doUpgrade(Role role, Object... params) {
        RoleEquip roleEquip = (RoleEquip) params[0];
        String opType = (String) params[1];
        Equip equip = (Equip) params[2];
        /**当前改造等级*/
        short currUpgradeLevel = roleEquip.queryUpgradeLevel();
        /**当前改造进度 百分比*/
        int oldUpgradeProgress = roleEquip.queryUpgradeProgress();
        /**当前改造进度数值*/
        int currJindu = roleEquip.getGaizaoJindu();
//        if (opType.equals(SIVER)) {
//            MessagePusher.pushMessage(role, new RespNotifyMiscEx("一键改造只能使用金元宝！"));
//            throw new IllegalArgumentException("只可以使用金元宝改造");
//        }

        /**扣除金钱*/
        roleService.subtractMoney(role, needCash(roleEquip.queryLevel(), 0), Reason.EQUIP_UPGRADE);
        log.error("角色=={},扣钱=={}", role.getName(), needCash(roleEquip.queryLevel(), 0));
        int rate = 1;
        int needGold = 0;
        int needSiver = 0;
        byte size = 0;
        int limitNum = 0;
        /**使用石头改造*/
        if (opType.contains("_")) {
            boolean limit = opType.split("_")[1].equals("1");//限制或者不限制
            size = Byte.parseByte(opType.split("_")[0]);
            if (roleEquip.queryEquipPos(false) == WEAPON) {
                limitNum += equipService.delRoloEquip(LINGSHI, size, limit, role);
            } else {
                limitNum += equipService.delRoloEquip(JINGSHI, size, limit, role);
            }
        } else {
            size = 6;
            /**一键改造 判断元宝*/
            if (roleEquip.queryUpgradeLevel() == 7){
                rate = 1;
            }else if (roleEquip.queryUpgradeLevel() == 8) {
                rate = 2;
            } else if (roleEquip.queryUpgradeLevel() == 9) {
                rate = 3;
            } else if (roleEquip.queryUpgradeLevel() == 10) {
                rate = 5;
            } else if (roleEquip.queryUpgradeLevel() == 11) {
                rate = 10;
            }
            if (opType.equals(GOLD)) {
                if (roleEquip.queryEquipPos(false) == WEAPON) {
                    needGold = 398 * 6;
                } else {
                    needGold = 108 * 6;
                }
                roleService.subtractGold(role, needGold, Reason.EQUIP_UPGRADE);
            } else {
                limitNum = 6;
                if (roleEquip.queryEquipPos(false) == WEAPON) {
                    needSiver = 398 * 6;
                } else {
                    needSiver = 108 * 6;
                }
                roleService.subtractSiver(role, needSiver, Reason.EQUIP_UPGRADE);
            }
            log.error("角色=={},改造扣除银元宝=={},金元宝={}", role.getName(), needSiver, needGold);

        }

        /**如果使用了限制道具增加限制交易时间*/
        if (limitNum >= 1) {
            roleEquip.addLimitTime(limitNum);
        }

        List<Integer> progressArr;
        int thisJindu = 0;
        double addJindu = 0.0;
        if (roleEquip.queryEquipPos(false) == WEAPON) {
            progressArr = WEAPON_PROGRESS;
            thisJindu = size * 398;
            addJindu = size * 398.0;
        } else {
            progressArr = ARMOR_PROGRESS;
            thisJindu = size * 108;
            addJindu = size * 108.0;
        }
        log.error("当前增加进度=[{}]", addJindu);
        addJindu = addJindu * rate;
        thisJindu = thisJindu * rate;
        log.error("当前增加进度=[{}]", addJindu);
        /**当前改造等级的满进度*/

        int fullJindu = progressArr.get(currUpgradeLevel);
        double lastProgress = (double) currJindu / (double) fullJindu;
        currJindu = thisJindu + currJindu;

        log.error("当前改造进度=[{}],满进度=[{}]", currJindu, fullJindu);

        /**这次改造之后的进度*/
        double thisProgress = (double) currJindu / (double) fullJindu;

        /**设置当前改造度*/
        roleEquip.setGaizaoJindu(currJindu);
        /**改造成功百分比*/
        roleEquip.alterUpgradeProgress((int) (thisProgress * 100.0 * 1000000.0));
        /**成功率*/
        int successRate = new Double((addJindu / fullJindu) * 1000000.0).intValue();

        boolean success;
        Random random = new Random();
        int randomValue = random.nextInt(1000000);
        /**如果改造完成了60%以上并且随机数比当前进度计算的成功率高*/
        if (thisProgress >= 0.85 || randomValue > successRate) {
            success = UPGRADE_FAIL;
        } else {
            success = UPGRADE_SUCCESS;
        }
        if (roleEquip.queryUpgradeLevel()>=10){
            success= UPGRADE_FAIL;
        }

        /**档改造进度大于本等级的满进度 必定成功*/
        if (currJindu >= fullJindu) {
            success = true;
        }
        final boolean boo = success;
        /**改造成功了*/
        if (success) {
            currUpgradeLevel++;
            /**改造等级+1*/
            roleEquip.alterUpgradeLevel(currUpgradeLevel);
            /**改造进度清0*/
            roleEquip.alterUpgradeProgress(0);
            /**改造进度*/
            roleEquip.setGaizaoJindu(0);

            /**判断当前的改造成功是否需要发谣言*/
            if (currUpgradeLevel > 5) {
                String msg;
                if (currUpgradeLevel > 8) {
                    msg = "惊闻玩家#Y%s#n成功将#R{%s}#n的改造等级提升到#R%d级#n了，得此神器，夫复何求啊！#49m";
                } else if (currUpgradeLevel == 8) {
                    msg = "#35m这难道就是传说中的神器吗？你们看，这就是#Y%s#n已经成功将#R{%s}#n改#R%d#n了......";
                } else if (currUpgradeLevel == 7) {
                    msg = "#63m天呐！#Y%s#n居然成功将#R{%s}#n的改造等级提升到#R%d级#n了！";
                } else {
                    msg = "#41m快来看啊！#Y%s#n成功将#R{%s}#n的改造等级提升到#R%d级#n了。";
                }
                equipService.sendEquipMsg(role, roleEquip, currUpgradeLevel, msg);
            }

//            pushOperateResult(role, UPGRADE_SUCCESS);
            /**增加改造成功属性*/
            equipService.addUpgradeField(equip, roleEquip);
            /**计算完美度*/
            equipService.countPerfect(roleEquip);
            /**刷新装备*/
            refreshRoleEquip(role, roleEquip);
            /**发下等级属性预览*/
            equipService.equipPreview(role, equip, roleEquip, UpgradeType.UPGRADE_EQUIP_UPGRADE);


            SpringUtils.getBean(ServerService.class).getScheduledExecutorService().schedule(new Runnable() {
                @Override
                public void run() {
                    RespGeneralNotify respGeneralNotify = new RespGeneralNotify();
                    respGeneralNotify.setValue(roleEquip.getPosition() + "_0");
                    respGeneralNotify.setNotify((short) NOTIFY_EQUIP_UPGRADE_OK);//武器改造成功
                    MessagePusher.pushMessage(role, respGeneralNotify);
                    RespOperateResult operateResult = new RespOperateResult();
                    operateResult.setSuccess(boo);
                    operateResult.setType("equip_upgrade#"+roleEquip.getPosition());
                    MessagePusher.pushMessage(role, operateResult);

                }
            },200, TimeUnit.MILLISECONDS);

            /**产生一个装备改造等级改变事件*/
            EventDispatcher.getInstance().fireEvent(new EquipUpgradeLevelChangeEvent(EventType.EQUIP_UPGRADE_LEVEL_CHANGE, role, roleEquip, currUpgradeLevel));
            return MessageFormat.format(SUCCESS, currUpgradeLevel - 1, currUpgradeLevel);

        } else {
//            refreshRoleEquip(role, roleEquip);
            SpringUtils.getBean(ServerService.class).getScheduledExecutorService().schedule(new Runnable() {
                @Override
                public void run() {
                    RespGeneralNotify respGeneralNotify = new RespGeneralNotify();
                    respGeneralNotify.setValue(roleEquip.getPosition() + "_0");
                    respGeneralNotify.setNotify((short) NOTIFY_EQUIP_UPGRADE_OK);//武器改造成功
                    MessagePusher.pushMessage(role, respGeneralNotify);
                    RespOperateResult operateResult = new RespOperateResult();
                    operateResult.setSuccess(boo);
                    operateResult.setType("equip_upgrade#"+roleEquip.getPosition());
                    MessagePusher.pushMessage(role, operateResult);
                }
            },200, TimeUnit.MILLISECONDS);
//            RespOperateResult operateResult = new RespOperateResult();
//            operateResult.setSuccess(success);
//            operateResult.setType(getUpdateTypeStr()+"#"+equip.getPosition());
//            MessagePusher.pushMessage(role, operateResult);
            return MessageFormat.format(FAIL, new BigDecimal((thisProgress - lastProgress) * 100.0).setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue(), new BigDecimal(thisProgress * 100.0).setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue());
        }
    }


    @Override
    public String acceptUpgrade(Role role, int upgradePos, String param) {
        RoleEquip roleEquip = equipService.getRoleEquipByPos(role, upgradePos);
        if (roleEquip == null) {
            return "请放入正确的装备。";
        }
        if (!isRightPosition(roleEquip.queryEquipPos(false))) {
            return MessageFormat.format(NO_RIGHT_POSITION, "改造", roleEquip.getName());
        }
        if (roleEquip.getType().equals("未鉴定装备")) {
            return MessageFormat.format(FAIL_MESSAGE, roleEquip.getName());
        }
        //去掉限制改造等级
//        if (roleEquip.queryUpgradeLevel()>=9){
//            return FAIL_MESSAGE1;
//        }
        Equip equip = EquipDataPool.getByName(roleEquip.getName());
        if (equip == null) {
            log.error("找不到装备配置ICON=[{}]", upgradePos);
            return MessageFormat.format(NOT_FIND_CONFIG, roleEquip.getName());
        }

        String noEnough = checkResource(role, param, roleEquip.queryLevel(), roleEquip);
        if (noEnough != null) {
            return noEnough;
        }


        return doUpgrade(role, roleEquip, param, equip);
    }

    @Override
    public String checkResource(Object... objects) {

        Role role = (Role) objects[0];
        String param = (String) objects[1];
        short level = (short) objects[2];
        RoleEquip roleEquip = (RoleEquip) objects[3];
        byte equipPos = roleEquip.queryEquipPos(false);

        int needGold = 0;
        int needSiver = 0;

        /**一键改造 判断元宝*/
        if (param.contains("_")) {
            boolean isUseLimit = param.split("_")[1].equals("1");
            byte size = Byte.parseByte(param.split("_")[0]);
            if (size <= 0) {
                return ERROR_OPTYPE;
            }
            if (roleEquip.queryUpgradeLevel() >= 4 && size < 2) {
                return "请放入最少2个或以上的道具。";
            }
            /**超级灵石*/
            int lingshiNum = equipService.getCount(LINGSHI, isUseLimit, role);
            /**超级晶石*/
            int jingShiNum = equipService.getCount(JINGSHI, isUseLimit, role);
            /**判断需要的资源是否足够*/

            if (equipPos == WEAPON) {
                if (lingshiNum < size) {
                    return MessageFormat.format(ROLE_RESOURCE_NOT_ENOUGH, LINGSHI);
                }
            } else {
                if (jingShiNum < size) {
                    return MessageFormat.format(ROLE_RESOURCE_NOT_ENOUGH, JINGSHI);
                }
            }
        } else {
            if (param.equals(GOLD)) {
                if (equipPos == WEAPON) {
                    needGold = 398 * 6;
                } else {
                    needGold = 108 * 6;
                }
                if (role.getGold() < needGold) {
                    return MessageFormat.format(ROLE_RESOURCE_NOT_ENOUGH, "金元宝");
                }
                /**一键改造 判断银元宝*/
            } else {
                if (equipPos == WEAPON) {
                    needSiver = 398 * 6;
                } else {
                    needSiver = 108 * 6;
                }
                if (role.getSiver() < needSiver) {
                    return MessageFormat.format(ROLE_RESOURCE_NOT_ENOUGH, "银元宝");
                }
                /**使用材料改造 判断材料*/
            }
        }

        if (level >= 70) {
            if (role.getMoney() < needCash(level, 0)) {
                return MessageFormat.format(ROLE_RESOURCE_NOT_ENOUGH, MONEY_NAME);
            }
        }
        return null;
    }

    /**
     * 这里的等级是装备的携带等级
     */
    @Override
    public int needCash(short level, int pos) {
        return level < 70 ? 0 : level * level * 16 + 5000;
    }

    @Override
    public String getUpdateTypeStr() {
        return "equip_upgrade";
    }
}
